﻿using Autofac;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Rhino.Mocks;
using WebFormsMvp.Contrib.Data.Services;
using WebFormsMvp.Contrib.Presenters;
using WebFormsMvp.Contrib.Views;

namespace WebFormsMvp.Contrib.Autofac.Tests
{
    /// <summary>
    /// Summary description for UnitTest1
    /// </summary>
    [TestClass]
    public class AutofacPresenterFactoryTests
    {
        [TestMethod]
        public void Instance_Of_Correct_Type()
        {
            //Arrange
            var view = MockRepository.GenerateMock<IAuthenticationView>();

            var builder = new ContainerBuilder();
            builder.RegisterPresenters(typeof(AuthenticationPresenter).Assembly);
            builder.Register<IAuthenticationService>(x => MockRepository.GenerateMock<IAuthenticationService>()).As<IAuthenticationService>();

            var kernel = new AutofacPresenterFactory(new StubContainerProvider(builder.Build()));

            var presenter = kernel.Create(typeof(AuthenticationPresenter), typeof(IAuthenticationView), view);
            //Act
            
            //Assert
            Assert.IsInstanceOfType(presenter, typeof(AuthenticationPresenter));
            Assert.AreSame(((AuthenticationPresenter)presenter).View, view);
        }

        [TestMethod]
        public void Multiple_Presenters_Are_Unique()
        {
            //Arrange
            var view = MockRepository.GenerateMock<IAuthenticationView>();

            var builder = new ContainerBuilder();
            builder.RegisterPresenters(typeof(CustomAuthenticationPresenter).Assembly);
            builder.Register<IAuthenticationService>(x => MockRepository.GenerateMock<IAuthenticationService>()).As<IAuthenticationService>();

            var kernel = new AutofacPresenterFactory(new StubContainerProvider(builder.Build()));

            var view2 = MockRepository.GenerateMock<IAuthenticationView>();

            var p1 = (CustomAuthenticationPresenter)kernel.Create(typeof(CustomAuthenticationPresenter), typeof(IAuthenticationView), view);
            var p2 = (CustomAuthenticationPresenter)kernel.Create(typeof(CustomAuthenticationPresenter), typeof(IAuthenticationView), view2);
            //Act

            //Assert
            Assert.AreNotSame(p1, p2);
        }

        [TestMethod]
        public void Presenters_Have_Unique_Views()
        {
            //Arrange
            var view = MockRepository.GenerateMock<IAuthenticationView>();

            var builder = new ContainerBuilder();
            builder.RegisterPresenters(typeof(CustomAuthenticationPresenter).Assembly);
            builder.Register<IAuthenticationService>(x => MockRepository.GenerateMock<IAuthenticationService>()).As<IAuthenticationService>();

            var kernel = new AutofacPresenterFactory(new StubContainerProvider(builder.Build()));

            var view2 = MockRepository.GenerateMock<IAuthenticationView>();

            var p1 = (CustomAuthenticationPresenter)kernel.Create(typeof(CustomAuthenticationPresenter), typeof(IAuthenticationView), view);
            var p2 = (CustomAuthenticationPresenter)kernel.Create(typeof(CustomAuthenticationPresenter), typeof(IAuthenticationView), view2);
            //Act

            //Assert
            Assert.AreNotSame(p1.View, p2.View);
        }

        [TestMethod]
        public void Preseters_Share_Service_Only()
        {
            //Arrange
            var view = MockRepository.GenerateMock<IAuthenticationView>();

            var builder = new ContainerBuilder();
            builder.RegisterPresenters(typeof(CustomAuthenticationPresenter).Assembly);
            builder.Register<IAuthenticationService>(x => MockRepository.GenerateMock<IAuthenticationService>()).As<IAuthenticationService>().SingleInstance();

            var kernel = new AutofacPresenterFactory(new StubContainerProvider(builder.Build()));

            var view2 = MockRepository.GenerateMock<IAuthenticationView>();

            var p1 = (CustomAuthenticationPresenter)kernel.Create(typeof(CustomAuthenticationPresenter), typeof(IAuthenticationView), view);
            var p2 = (CustomAuthenticationPresenter)kernel.Create(typeof(CustomAuthenticationPresenter), typeof(IAuthenticationView), view2);
            //Act

            //Assert
            Assert.IsNotNull(p1.DataService);
            Assert.IsNotNull(p2.DataService);
            Assert.AreSame(p1.DataService, p2.DataService);
            Assert.AreNotSame(p1.View, p2.View);
        }

        [TestMethod]
        public void Presenter_Create_With_Service()
        {
            //Arrange
            var view = MockRepository.GenerateMock<INewsArchiveView>();

            var builder = new ContainerBuilder();
            builder.RegisterPresenters(typeof(NewsArchivePresenter).Assembly);
            builder.Register<INewsService>(x => MockRepository.GenerateMock<INewsService>()).As<INewsService>().SingleInstance();

            var kernel = new AutofacPresenterFactory(new StubContainerProvider(builder.Build()));

            var presenter = kernel.Create(typeof(NewsArchivePresenter), typeof(INewsArchiveView), view);
            //Act

            //Assert
            Assert.IsInstanceOfType(presenter, typeof(NewsArchivePresenter));
        }
    }
}
